package drds.configuration.db;

import drds.configuration.common.Constants;
import drds.configuration.db.table_mapping.UseConnection;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcUtil {
    /**
     * 整个框架最核心的数据库更新操作方法
     */
    @UseConnection
    public static int update(Connection connection, String sql, Object... parameters) throws SQLException {
        if (Constants.devMode) {
            Db.log.debug("sql:" + sql);
        }
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        int length = parameters.length;
        for (int i = 0; i < length; i++) {
            preparedStatement.setObject(i + 1, parameters[i]);
        }
        int result = preparedStatement.executeUpdate();
        close(preparedStatement);
        return result;
    }


    /**
     * 查询--底层方法
     */
    @UseConnection
    public static <T> List<T> query(Connection connection, String sql, Object... parameters) throws SQLException {
        if (Constants.devMode) {
            Db.log.debug("sql:" + sql);
        }
        List list = new ArrayList();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        int length = parameters.length;
        for (int i = 0; i < length; i++) {
            preparedStatement.setObject(i + 1, parameters[i]);
        }
        ResultSet resultSet = preparedStatement.executeQuery();
        int columnCount = resultSet.getMetaData().getColumnCount();
        if (columnCount > 1) {
            while (resultSet.next()) {
                Object[] objects = new Object[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    objects[i] = resultSet.getObject(i + 1);
                }
                list.add(objects);
            }
        } else if (columnCount == 1) {
            while (resultSet.next()) {
                list.add(resultSet.getObject(1));
            }
        }
        close(resultSet, preparedStatement);
        return list;
    }

    /**
     * 不支持事务的连接获取方法
     */
    public static final Connection getConnection(DataSource dataSource) throws SQLException {
        if (dataSource == null) {
            Db.log.error("请初始化数据源");
            throw new RuntimeException("请初始化数据源");
        }
        Connection connection = dataSource.getConnection();
        if (connection != null && !connection.isClosed()) {
            return connection;
        } else {
            return null;
        }

    }

    public static final void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
                Db.log.error(e.getMessage());
            }
        }
    }

    public static final void close(ResultSet resultSet, Statement statement, Connection connection) {
        close(resultSet);
        close(statement);
        close(connection);
    }

    public static final void close(Statement statement, Connection connection) {
        close(statement);
        close(connection);
    }

    public static final void close(ResultSet resultSet, Statement statement) {
        close(resultSet);
        close(statement);
    }

    public static final void close(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                Db.log.error("Statement实例不能关闭" + e.getMessage());
            } finally {
                statement = null;
            }
        }
    }

    public static final void close(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                Db.log.error("ResultSet实例不能关闭" + e.getMessage());
            } finally {
                resultSet = null;
            }
        }

    }

    // 事务处理
    public static final void setAutoCommit(Connection connection, Boolean value) {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.setAutoCommit(value);
            } else {
                throw new SQLException("connection is null or isClosed");
            }
        } catch (SQLException e) {
            Db.log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    public static final void commit(Connection connection) {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.commit();
            } else {
                throw new SQLException("connection is null or isClosed");
            }
        } catch (SQLException e) {
            Db.log.error(e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }

    public static final void rollback(Connection connection) {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.rollback();
            } else {
                throw new SQLException("connection is null or isClosed");
            }
        } catch (SQLException e) {
            Db.log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }
}
